/* Compile me with:  jflex mini.lex  */
package lex;



%%

%class Scanner
%line
%column
%type Token


%{
Token tok(String tag) { 

        if(tag == "◇"){
                return new Token(yytext(), yycolumn+1, yytext(), yyline);
        }else{
                return new Token(tag, yycolumn+1, yytext(), yyline);
        }
}
%}

/* This method deals with error cases */
%{
Token errorHandler(int error) { 
        switch (error) {
            case 1:  return new Token(yytext(), yycolumn+1, yytext(), yyline, 1); /*ERRORCOMMENT*/
            case 2:  return new Token(yytext(), yycolumn+1, yytext(), yyline, 2); /*NONIDENTIFIER*/
            case 3:  return new Token(yytext(), yycolumn+1, yytext(), yyline, 3); /*INVALIDCHAR*/
            case 5:  return new Token(yytext(), yycolumn+1, yytext(), yyline, 5); /*NOTNUM*/
            default: return new Token(yytext(), yycolumn+1, yytext(), yyline, 0);
        }
}
%}

        


INT = [0-9]+

DQUOTE = "\""


/*Itai's macros*/

NUM = [1-9]+ [0-9]* | "0"
NOTNUM = "0"{INT}



/*Nadav's macros*/

BACKSLASH = "\\"
DBSLASH = "\\\\"
AQUTE = "\\\""
TAB = "\\t"
NEWLINE = "\\n"

Char = [a-zA-Z]
Digits = [0-9]
Whitespace = " "
Symbols = "!" |[#-/] | [:-@] | "[" | "]" | "^" | "_" | "`" | [{-~] 
StringChar = {Char} | {Digits} |{Whitespace} |{Symbols} | {DBSLASH} | {AQUTE} |{TAB} |{NEWLINE}


STR = ({DQUOTE}{StringChar}*{DQUOTE})

NotStringChar = [\x00-\x1f] | {DQUOTE} | {BACKSLASH}

NotString = ({DQUOTE}{NotStringChar}+{DQUOTE}) | {DQUOTE}  | {BACKSLASH}

      
        
/*Gil's macros*/

/* Macros for operators */
ARITHMETICOP = [+-/*\^!\%]
EQUALITYOPS = [=!][=]{0,1}
RELATIONALOP = [<>][=]{0,1}
CONDITIONALOP = [&]{2} | [|]{2}
UNARYOP = [!]  /*for booleans*/
OPERATORS = {ARITHMETICOP}|{EQUALITYOPS}|{RELATIONALOP}|{CONDITIONALOP}|{UNARYOP}

/* Macros for identifiers */
IDENTIFIER = ([a-z][a-zA-Z0-9_]*)*
CLASSIDENTIFIER = ([A-Z][a-z0-9_]*)*    
NONIDENTIFIER = "_"{IDENTIFIER} | "_"{CLASSIDENTIFIER}

/* Macros for comments */
InputCharacter = [^\r\n]
LineTerminator = \r|\n|\r\n
EndOfLineComment = "//" {InputCharacter}* {LineTerminator}
TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" | "/*" ~"*/"
Comment = {TraditionalComment} | {EndOfLineComment}
ERRORCOMMENT = "/*"

/* Macros for whitespaces */
TabSpace = \t
WhiteSpace = {LineTerminator} | [ \t\f] | TabSpace

/* Macros for invalid character*/


%%


/* Keywords - Gil */

        "boolean"       { return tok("boolean"); }
        "break"         { return tok("break"); }
        "class"         { return tok("class"); }
        "continue"      { return tok("continue"); }
        "else"          { return tok("else"); }
        "extends"       { return tok("extends"); } 
        "false"         { return tok("false"); }
        "if"            { return tok("if"); }
        "int"           { return tok("int"); }
        "length"        { return tok("length"); }
        "new"           { return tok("new"); }
        "null"          { return tok("null"); }
        "return"        { return tok("return"); }
        "static"        { return tok("static"); }  
        "string"        { return tok("string"); }
        "this"          { return tok("this"); }
        "true"          { return tok("true"); }
        "void"          { return tok("void"); }
        "while"         { return tok("while"); }


/* identifiers, class identifiers - Gil */

{IDENTIFIER}                    { return tok("ID"); }
{CLASSIDENTIFIER}               { return tok("CLASS_ID"); }
/* error case*/
{NONIDENTIFIER}                 { return errorHandler(2); }


/* separators - Gil*/
  "("                            { return tok("("); }
  ")"                            { return tok(")"); }
  "{"                            { return tok("{"); }
  "}"                            { return tok("}"); }
  "["                            { return tok("["); }
  "]"                            { return tok("]"); }
  ";"                            { return tok(";"); }
  ","                            { return tok(","); }
  "."                            { return tok("."); }


/* Numeric literals - Itai */

{NUM}       { return tok("INTEGER"); }
{NOTNUM}    { return errorHandler(5); }


/*Operators - Gil */
{OPERATORS}                     { return tok("◇"); }


/* Strings literal - Nadav */

{STR} { return tok("STRING"); }
{NotString} { return errorHandler(4); } 


/* comments - Gil */

{Comment}              { /* nothing; skip */ }
/* error case*/
{ERRORCOMMENT}          { return errorHandler(1); }     

/* whitespace - Gil */

{WhiteSpace} { /* ignore */ }


/*This MUST be last*/

.       { return errorHandler(3); }